<?php

namespace app\common\lib\file_operate;

class MakeZip
{

    /**

     * 文件解压方法

     * $fileName 文件地址 绝对路径

     * $outPath  文件解压地址 绝对路径

     */

    public static function unZip($fileName = "", $outPath = '')
    {

        $res = ['status' => 'success', 'message' => '解压完成', 'code' => 200];

        $zip = new \ZipArchive();

        try {

            if (!file_exists($outPath)) {

                mkdir($outPath, 0777, true);

            }

            $openRes = $zip->open($fileName);

            if ($openRes === true) {

                $zip->extractTo($outPath);

                $zip->close();

                unlink($fileName);

            } else {

                $res['status'] = 'error';

                $res['message'] = '压缩文件打开失败';

                $res['code'] = 101;

            }

        } catch (\Exception $e) {

            $res['status'] = 'error';

            $res['message'] = '解压异常：' . $e->getMessage();

            $res['code'] = 102;

            //throw new \Exception( '解压异常：'.$e->getMessage() ) ;

        }

        return $res;

    }

    /**

     * 生成压缩包

     * @param $dir_path  想要压缩的目录：如 F:\zip

     * @param $zipName   压缩后的文件名：如 F:\cc.zip

     * @return [type]           [description]

     */

    public function zip($dir_path, $zipName)
    {

        $relationArr = array(

            $dir_path => array(

                'originName' => $dir_path,

                'is_dir'     => true,

                'children'   => array(),

            ),

        );

        $key = array_keys($relationArr);

        $zip = new \ZipArchive();

        if ($zip->open($zipName, \ZipArchive::CREATE) !== true) {

            return ['status' => 'error', 'message' => '文件创建失败', 'code' => 101];

        }

        //遍历要压缩的目录

        $this->modifiyFileName($dir_path, $relationArr[$dir_path]['children']);

        //文件打包压缩

        $name = substr($dir_path, strrpos($dir_path, '\\') + 1, strlen($dir_path));

        $this->zipDir($key[0], $name, $zip, $relationArr[$dir_path]['children']);

        $zip->close(); //关闭

        return ['status' => 'success', 'message' => '压缩成功', 'code' => 200];

    }

    /**

     * 获取全部文件目录

     */

    public function modifiyFileName($path, &$relationArr)
    {

        if (!is_dir($path) || !is_array($relationArr)) {

            return false;

        }

        //opendir打开一个目录，在失败的时候返回一个空的指针。

        if ($dh = opendir($path)) {

            //readdir打开一个目录，读取它的内容，然后关闭：

            while (($file = readdir($dh))) {

                if (in_array($file, array('.', '..', null))) {
                    continue;
                }
                //无效文件，重来

                if (is_dir($path . DS . $file)) {

                    $relationArr[$file] = array(

                        'originName' => $file, //mb_convert_encoding($file, 'UTF-8', 'GBK'),

                        'is_dir'     => true,

                        'children'   => array(),

                    );

                    $this->modifiyFileName($path . DS . $file, $relationArr[$file]['children']);

                } else {

                    $extension = strchr($file, '.');

                    $relationArr[$file] = array(

                        'originName' => $file, //mb_convert_encoding($file, 'UTF-8', 'GBK'),

                        'is_dir'     => false,

                        'children'   => array(),

                    );

                }

            }

        }

    }

    public function zipDir($real_path, $zip_path, &$zip, $relationArr)
    {

        $sub_zip_path = empty($zip_path) ? '' : $zip_path . '\\';

        if (is_dir($real_path)) {

            foreach ($relationArr as $k => $v) {

                if ($v['is_dir']) {
                    //是文件夹

                    $zip->addEmptyDir($sub_zip_path . $v['originName']);

                    $this->zipDir($real_path . '\\' . $k, $sub_zip_path . $v['originName'], $zip, $v['children']);

                } else {
                    //不是文件夹

                    $zip->addFile($real_path . '\\' . $k, $sub_zip_path . $k);

                    // $zip->deleteName($sub_zip_path . $v['originName']);

                    // $zip->renameName($sub_zip_path . $k, $sub_zip_path . $v['originName']);

                }

            }

        }

    }

}
